/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.helper;

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.domain.Customer;
import org.domain.Item;
import org.domain.ItemShippingStatusList;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
 *
 * @author davidsciacchettano
 */
public class ShipGoods {

    private String url = "http://localhost:9080/RetailServicerOrderWsdlService/RetailServicerOrderWsdlPort";
    private String xmlRequest;
    private HttpURLConnection con;
    private int requestResponse;
    private ArrayList<Item> order = new ArrayList<Item>();
    private ArrayList<Item> shippedItems = new ArrayList<Item>();
    private ArrayList<Item> notShippedItems = new ArrayList<Item>();
    private Customer customer;
    private ItemShippingStatusList issl = new ItemShippingStatusList();

    public ShipGoods(ArrayList<Item> o, Customer cust) {
        
        
        this.setOrder(o);
        this.setCustomer(cust);

        this.createRequestString();
        this.createConnection();
        this.requestResponse = this.sendRequest();

        //make sure the request worked
        if(this.requestResponse == 200) {
            this.parseResponse();
            this.buildReturnList(); 
        }
        
    }

    private void setCustomer(Customer c) {
        //perform a deep copy
        customer = new Customer(c.getCustomerRef(), c.getName(), c.getAddress1(), c.getAddress2(),
                c.getCity(), c.getProvince(), c.getPostalCode(), c.getCountry());
    }

    private void setOrder(ArrayList<Item> o) {        
        for(int i = 0; i < o.size(); i++) {
            //System.out.println(o.get(i));
            order.add(o.get(i));
        }
    }

    public ArrayList<Item> getOrder() {
        return this.order;
    }

    public ArrayList<Item> getShippedItems() {
        return this.shippedItems;
    }

    public ArrayList<Item> getNotShippedItems() {
        return this.notShippedItems;
    }

    public Customer getCustomer() {
        return this.customer;
    }

    private void createRequestString() {
        this.xmlRequest = "<soapenv:Envelope xsi:schemaLocation=\"http://schemas.xmlsoap.org/soap/envelope/ http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ret=\"http://xml.netbeans.org/schema/RetailServiceOrderXSD\">" +
                          "<soapenv:Body>" +
                          "<ret:orderRequest>";

        //loop thru the order and add to the xml request
        for(int i = 0; i < order.size(); i++) {
            if(order.get(i).getQuantity() > 0) {
                xmlRequest += "<items>" +
                    "<manufacturerName>" + order.get(i).getManufacturer() + "</manufacturerName>" +
                    "<productType>" + order.get(i).getProduct() + "</productType>" +
                    "<quantity>" + order.get(i).getQuantity() + "</quantity>" +
                    "<unitPrice>" + order.get(i).getPrice() + "</unitPrice>" +
                    "</items>";
            }

        }

        //add customer information to the order request
        xmlRequest += "<customer>" +
                            "<city>" + customer.getCity() + "</city>" +
                            "<country>" + customer.getCountry() + "</country>" +
                            "<customerReferenceNumber>" + customer.getCustomerRef() + "</customerReferenceNumber>" +
                            "<name>" + customer.getName() + "</name>" +
                            "<state>" + customer.getProvince() + "</state>" +
                            "<street1>" + customer.getAddress1() + "</street1>" +
                            "<street2>" + customer.getAddress2() + "</street2>" +
                            "<zip>" + customer.getPostalCode() + "</zip>" +
                        "</customer>" +
                     "</ret:orderRequest>" +
                  "</soapenv:Body>" +
              "</soapenv:Envelope>";
                              
                              
    }

    /*
     * Create a connection.
     */
    private void createConnection() {
        try {
            con = (HttpURLConnection) new URL(url).openConnection();

            con.setRequestMethod("POST");
            con.setRequestProperty("Content-Type", "text/xml; charset=utf-8");

            con.setDoInput(true);
            con.setDoOutput(true);
         
        } catch(IOException ioe) {
            ioe.printStackTrace();
        }
    }

    /*
     * Send the request to the BPEL module.
     */
    private int sendRequest() {
        int response = -1;
        try {
            DataOutputStream dos = new DataOutputStream(con.getOutputStream());
            dos.writeBytes(this.xmlRequest);
            dos.flush();
            dos.close();
            response = con.getResponseCode();
        }catch(IOException ioe) {
            ioe.printStackTrace();
        }

        return response;
    }

    /*
     * This method will parse the xml response.
     */
    private void parseResponse() {
        Item tmpItem;
        Customer c;

        //make sure the response went thru
        if(requestResponse == 200) {
            try {
                InputStream is = con.getInputStream();

                Document doc = null;
                DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
                DocumentBuilder db = null;

                db = dbf.newDocumentBuilder();
                doc = db.parse(is);
                doc.getDocumentElement().normalize();

                //parse the xml response
                //get the <return> tag which contains the cust, zero or more itemList
                //zero or more shippedItems, zero or more notShippedItems.
                NodeList returnNode = doc.getElementsByTagName("return");
                
                System.out.println("Size of nodes:" + returnNode.getLength());
                //loop through all the return nodes
                for(int i = 0; i < returnNode.getLength(); i++) {
                    //get child nodes
                    NodeList children = returnNode.item(i).getChildNodes();
                    
                    for(int x = 0; x < children.getLength(); x++) {
                        //System.out.println("Order: " + children.item(x));
                        
                        //check for customer data
                        if(children.item(x).getNodeName().equals("shippedItems")) {
                            //get the child nodes and parse thru them to create the Item object.
                            NodeList itemList = children.item(x).getChildNodes();
                            
                            //create an item and set it tothe order arraylist
                            tmpItem = new Item();
                            tmpItem.setManufacturer(itemList.item(0).getChildNodes().item(0).getNodeValue());
                            tmpItem.setProduct(itemList.item(1).getChildNodes().item(0).getNodeValue());
                            tmpItem.setQuantity(Integer.parseInt(itemList.item(2).getChildNodes().item(0).getNodeValue()));
                            tmpItem.setPrice(Float.parseFloat(itemList.item(3).getChildNodes().item(0).getNodeValue()));
                            
                            //add the itemList to the order
                            shippedItems.add(tmpItem);
                            
                            //System.out.println("Item: " + tmpItem);

                        }
                        
                        if(children.item(x).getNodeName().equals("notShippedItems")) {
                            //get the child nodes and parse thru them to create the Item object.
                            NodeList itemList = children.item(x).getChildNodes();
                            
                            //create an item and set it tothe order arraylist
                            tmpItem = new Item();
                            tmpItem.setManufacturer(itemList.item(0).getChildNodes().item(0).getNodeValue());
                            tmpItem.setProduct(itemList.item(1).getChildNodes().item(0).getNodeValue());
                            tmpItem.setQuantity(Integer.parseInt(itemList.item(2).getChildNodes().item(0).getNodeValue()));
                            tmpItem.setPrice(Float.parseFloat(itemList.item(3).getChildNodes().item(0).getNodeValue()));
                            
                            //add the itemList to the order
                            notShippedItems.add(tmpItem);
                            
                            //System.out.println("Item: " + tmpItem);

                        }
                    }
                    
                    
                }

            }catch(IOException ioe) {
                ioe.printStackTrace();
            }catch(ParserConfigurationException pce) {
                pce.printStackTrace();
            }catch(SAXException se) {
                se.printStackTrace();
            }
        }
    }
    
    /*
     * Method will build the ItemShippingStatuslist
     */
    private void buildReturnList() {
        //add all the arrays to the return type, making sure 
        //add the custoemr
        issl.setCust(this.customer);
        issl.setItemList(this.order);
        
        //make suris data in the other arrays
        if(this.shippedItems.size() > 0) {
            issl.setShippedItems(this.shippedItems);
        }
        
        if(this.notShippedItems.size() > 0) {
            issl.setNotShippedItems(notShippedItems);
        }
    }
    
    public ItemShippingStatusList getItemShippedStatusList() {
        return this.issl;
    }

    public static void main(String args[]) {
        Item i1, i2, i3;
        Customer c = new Customer(1, "John Mayor", "1234 Some St.", "n/a", "Montreal",
                "Quebec", "H0H 0H0", "Canada");
        i1 = new Item(1, "manufacturer1", "DVD Player", 50, Float.parseFloat("25.00"));
        i2 = new Item(2, "manufacturer2", "TV", 50, Float.parseFloat("25.00"));
        i3 = new Item(3, "manufacturer2", "DVD Player", 50, Float.parseFloat("25.00"));

        ArrayList<Item> i = new ArrayList<Item>();
        i.add(i1);
        i.add(i2);
        i.add(i3);

        ShipGoods sg = new ShipGoods(i, c);
        
        ItemShippingStatusList issl = sg.getItemShippedStatusList();
        ArrayList<Item> list = issl.getShippedItems();
        
        for(int a = 0; a < list.size(); a++) {
            System.out.println("Shipped Item:  " + list.get(a));
        }
    }
}
